/* eslint-disable no-param-reassign */
import { useRef, useState, useEffect, useCallback } from 'react';
import JRPCSocket from './json-rpc-websocket';

function useRPC(updateChartData, updateDataInformation, visible, callback) {
  const JPRCtask = useRef({ socket: null, receivable: true, uri: null }).current;
  const intervalBeatRef = useRef(null);

  const [taskMessage, setTaskMessage] = useState(null);
  const [runState, setRunState] = useState(false);
  const [dataEndpoint, setDataEndpoint] = useState(null);

  const handleDataForChart = (data) => {
    const { receivable } = JPRCtask;

    if (data) {
      // window.console.log(data);
      data.dataCollection.forEach((item) => {
        // window.console.log(
        //   `${item.angle}-${item.startFrequency}-${item.stopFrequency}-${item.polarization}-${item.percent}`,
        // );
        if (item.type === 'fastTestData') {
          const {
            totalPoints,
            data: { antennaMeasure },
          } = item;
          if (totalPoints && antennaMeasure && totalPoints > antennaMeasure.length) {
            const undefs = [];
            for (let i = 0; i < totalPoints - antennaMeasure.length; i += 1) {
              undefs.push(undefined);
            }
            item.data.antennaGain = [...item.data.antennaGain, ...undefs];
            item.data.antennaMeasure = [...item.data.antennaMeasure, ...undefs];
            item.data.meter = [...item.data.meter, ...undefs];
            item.data.originMeter = [...item.data.originMeter, ...undefs];
            item.data.noiseTemperature = [...item.data.noiseTemperature, ...undefs];
            item.data.psd1 = [...item.data.psd1, ...undefs];
            item.data.psd2 = [...item.data.psd2, ...undefs];
            item.data.systemGain = [...item.data.systemGain, ...undefs];
          }
          // window.console.log('------------------------------------');
          // window.console.log(item.data.meter, item.data.originMeter);
          updateChartData(item.data.originMeter);
          callback?.(item);
          if (receivable) {
            updateDataInformation(item.data);
          }
        }
      });
    }
  };

  const reconnectTimerRef = useRef(null);

  const initTask = useCallback((url) => {
    const socket = new JRPCSocket({
      url,
      onopen: () => {
        JPRCtask.receivable = true;
        clearInterval(intervalBeatRef.current);
        intervalBeatRef.current = setInterval(() => {
          JPRCtask.socket?.send?.({
            id: 1,
            method: 'heartbeat',
          });
        }, 3000);
      },
      onmessage: (res) => {
        if (res.params && res.params instanceof Object) {
          handleDataForChart(res.params);
        }
      },
      // onerror: (err) => {
      //   window.console.log(err);
      // },
      onclose: () => {
        const { visible: v1, uri: u1, socket: sk1 } = JPRCtask;
        if (v1 && u1 && sk1 && !reconnectTimerRef.current) {
          reconnectTimerRef.current = setTimeout(() => {
            const { visible: v2, uri: u2, socket: sk2 } = JPRCtask;
            if (v2 && u2 && sk2) {
              window.console.log('with1');
              sk2?.withUrl(u2);
            }
            reconnectTimerRef.current = null;
          }, 3000);
        }
      },
    });
    JPRCtask.socket = socket;
  }, []);

  useEffect(() => {
    if (dataEndpoint?.uri && visible) {
      JPRCtask.receivable = false;
      JPRCtask.uri = dataEndpoint.uri;
      if (!JPRCtask.socket) {
        initTask(dataEndpoint.uri);
      } else {
        const { current } = reconnectTimerRef;
        window.console.log(current);
        if (current) {
          clearTimeout(current);
          reconnectTimerRef.current = null;
        }
        const { visible: v2, uri: u2, socket: sk2 } = JPRCtask;
        if (v2 && u2 && sk2) {
          window.console.log('with2');
          sk2?.withUrl(u2);
        }
      }
    } else {
      window.console.log('close2');
      JPRCtask.socket?.close();
      JPRCtask.socket = null;
      JPRCtask.receivable = false;
      JPRCtask.uri = null;
    }
  }, [JSON.stringify(dataEndpoint), visible]);

  useEffect(() => {
    JPRCtask.visible = visible;
    if (visible === false) {
      setDataEndpoint(null);

      const { current } = reconnectTimerRef;
      if (current) {
        clearTimeout(current);
        reconnectTimerRef.current = null;
      }
    }
  }, [visible]);

  useEffect(() => {
    return () => {
      if (JPRCtask.socket) {
        JPRCtask.socket.close();
        JPRCtask.socket = null;
        JPRCtask.receivable = false;
      }
    };
  }, []);

  return {
    JPRCtask,
    dataEndpoint,
    setDataEndpoint,
    taskMessage,
    setTaskMessage,
    runState,
    setRunState,
  };
}

export default useRPC;
